package com.glsc.ngateway.opmanage.controller;

import com.glsc.ngateway.common.api.common.enums.PageConstant;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.Dict;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.MysqlDataDictionary;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.MysqlDictFieldMap;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.MysqlDictFieldMapId;
import com.glsc.ngateway.common.api.platform.resp.PlatformResponse;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.MysqlDataDictionaryRepository;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.MysqlDictFieldMapRepository;
import com.glsc.ngateway.opmanage.utils.JsonTool;
import com.glsc.ngateway.opmanage.utils.SpecificationFactory;
import com.glsc.ngateway.opmanage.service.DictService;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.hibernate.exception.ConstraintViolationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.persistence.criteria.Predicate;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@RestController
public class DictFieldMapController {

    @Autowired
    MysqlDictFieldMapRepository mysqlDictFieldMapRepository;

    @Autowired
    MysqlDataDictionaryRepository mysqlDataDictionaryRepository;

    private DictService dictService;

    @Autowired
    public void setDictService(DictService dictService) {
        this.dictService = dictService;
    }

    /*
     *  http://localhost:8090/glamApi/dictFieldMap/listPage?pageNumber=1&pageSize=10
     * */
    @GetMapping("/dictFieldMap/listPage")
    public PlatformResponse<Page<MysqlDictFieldMap>> listPage(
            @RequestParam(value = "pageNumber", required = false) Integer pageNumber,
            @RequestParam(value = "pageSize", required = false) Integer pageSize) {

        PlatformResponse<Page<MysqlDictFieldMap>> ret;
        try {
            if (pageNumber == null) {
                pageNumber = 1;
            }
            if (pageSize == null) {
                pageSize = PageConstant.PageSize;
            }

            Sort sort = Sort.by(Direction.ASC, "tableName", "fieldName");
            Pageable pageable = PageRequest.of(pageNumber - 1, pageSize, sort);
            Page<MysqlDictFieldMap> dto = mysqlDictFieldMapRepository.findAll(pageable);

            ret = PlatformResponse.successData(dto);
        } catch (Exception e) {
            ret = PlatformResponse.failedMsg(e.getMessage());
        }
        return ret;
    }

    /**
     * http://localhost:8090/glamApi/dictFieldMap/listPageBy?dictSpace=GLOBAL&fieldName=PERIOD_TYPE
     *
     * @param pageNumber
     * @param pageSize
     * @param dictSpace
     * @param fieldName
     * @return
     */
    @GetMapping("/dictFieldMap/listPageBy")
    public PlatformResponse<Page<MysqlDictFieldMap>> listPageBy(
            @RequestParam(value = "pageNumber", required = false) Integer pageNumber,
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
            @RequestParam(value = "dictSpace", required = false) String dictSpace,
            @RequestParam(value = "fieldName", required = false) String fieldName) {

        PlatformResponse<Page<MysqlDictFieldMap>> ret;
        try {
            if (pageNumber == null) {
                pageNumber = 1;
            }
            if (pageSize == null) {
                pageSize = PageConstant.PageSize;
            }

            Sort sort = Sort.by(Direction.ASC, "tableName", "fieldName");
            Pageable pageable = PageRequest.of(pageNumber - 1, pageSize, sort);
//		    Page<MysqlDictFieldMap> dto = mysqlDictFieldMapRepository.findAll(pageable);

            Page<MysqlDictFieldMap> dto = mysqlDictFieldMapRepository.findAll((root, query, cb) -> {
                Predicate predicate = root.isNotNull();

                if (!StringUtils.isEmpty(dictSpace)) {
                    predicate = cb.and(predicate, cb.equal(root.get("dictSpace"), dictSpace));
                }
                if (!StringUtils.isEmpty(fieldName)) {
                    predicate = cb.and(predicate, cb.equal(root.get("fieldName"), fieldName));
                }

                return predicate;
            }, pageable);


            ret = PlatformResponse.successData(dto);
        } catch (Exception e) {
            ret = PlatformResponse.failedMsg(e.getMessage());
        }
        return ret;
    }

    /**
     * http://localhost:8090/glamApi/dictFieldMap/listDataDictonary?tableName=BATCH_TASK_DEFINE&fieldName=PERIOD_TYPE
     */
    @GetMapping("/dictFieldMap/listDataDictonary")
    public PlatformResponse<Object> listDataDictonary(
            @RequestParam(value = "tableName", required = true) String tableName,
            @RequestParam(value = "fieldName", required = true) String fieldName) {

        PlatformResponse<Object> ret;
        try {
            Optional<MysqlDictFieldMap> dfm = mysqlDictFieldMapRepository.findById(new MysqlDictFieldMapId(tableName, fieldName));
            Object dto = dfm.map(r -> mysqlDataDictionaryRepository.findByFieldName(r.getDictField())).orElse(null);
            return PlatformResponse.successData(dto);
        } catch (Exception e) {
            ret = PlatformResponse.failedMsg(e.getMessage());
        }
        return ret;
    }

    /**
     * http://localhost:8090/glamApi/dictFieldMap/listDataDictonaryMap?dictFieldName=BENCH_TYPE
     */
    @GetMapping("/dictFieldMap/listDataDictonaryMap")
    public PlatformResponse<Map<String, String>> listDataDictonaryMap(
            @RequestParam(value = "dictFieldName", required = true) String dictFieldName) {

        PlatformResponse<Map<String, String>> ret;
        try {
            List<MysqlDataDictionary> items = mysqlDataDictionaryRepository.findByFieldName(dictFieldName);
            Map<String, String> map = new HashMap<String, String>();
            if (items != null) {
                for (MysqlDataDictionary item : items) {
                    map.put(item.getfCode(), item.getfValues());
                }
            }
            ret = PlatformResponse.successData(map);
        } catch (Exception e) {
            ret = PlatformResponse.failedMsg(e.getMessage());
        }
        return ret;
    }

    /*
     * http://localhost:8090/glamApi/dictFieldMap/addUpt
     *
     * */
    @PostMapping("/dictFieldMap/addUpt")
    public PlatformResponse<?> add(HttpServletRequest request, @RequestBody MysqlDictFieldMap mysqlDictFieldMap) {

        PlatformResponse<?> response = null;
        try {
//			String token = (String)request.getAttribute(AttributeNames.token.getVal());	
            mysqlDictFieldMapRepository.save(mysqlDictFieldMap);
            response = PlatformResponse.success();
        } catch (DataIntegrityViolationException e) {
            if (e.getCause() instanceof ConstraintViolationException) {
                response = PlatformResponse.failedMsg(((ConstraintViolationException) e.getCause()).getSQLException().getMessage());
            } else {
                response = PlatformResponse.failedMsg(e.getMessage());
            }
        } catch (Exception e) {
            response = PlatformResponse.failedMsg(e.getMessage());
        }
        return response;
    }

    //  @PageAccessAnnotation(operMenu = "系统管理-字典管理",operType = "新建",operDesc = "新建字典")
    @PostMapping("/dict/create")
    @ApiOperation(value = "创建字典项信息", notes = "创建字典项信息")
    public PlatformResponse<Void> create(@RequestBody Dict dict) {
        dictService.add(dict);
        return PlatformResponse.successMsg("创建成功");
    }

    @PostMapping("/dict/createfund")
    @ApiOperation(value = "创建渠道字典项信息", notes = "创建渠道字典项信息")
    public PlatformResponse<Void> createFund(@RequestBody Dict dict) {
        dictService.addFundDict(dict);
        return PlatformResponse.successMsg("创建成功");
    }

    @PostMapping("/dict/createfunddata")
    @ApiOperation(value = "创建策略字典项信息", notes = "创建策略字典项信息")
    public PlatformResponse<Void> createFundData(@RequestBody MysqlDataDictionary mysqlDataDictionary) {
        dictService.addFundDictDate(mysqlDataDictionary);
        return PlatformResponse.successMsg("创建成功");
    }

    //  @PageAccessAnnotation(operMenu = "系统管理-字典管理",operType = "编辑",operDesc = "编辑字典")
    @PostMapping("/dict/update")
    @ApiOperation(value = "更新字典项信息")
    public PlatformResponse<Void> update(@RequestBody Dict dict) {
        dictService.update(dict);
        return PlatformResponse.successMsg("更新成功");
    }

    // @PageAccessAnnotation(operMenu = "系统管理-字典管理",operType = "删除",operDesc = "删除字典")
    @PostMapping("/dict/delete")
    @ApiOperation(value = "删除字典项信息")
    public PlatformResponse<Void> delete(@RequestBody String param) {
        Long dictMapId = JsonTool.parseJsonId(param);
        if (dictMapId == null || dictMapId < 0) {
            return PlatformResponse.failedMsg("id参数错误");
        }
        if (dictService.delete(dictMapId) == 1) {
            return PlatformResponse.successMsg("删除成功");
        } else {
            return PlatformResponse.failedMsg("未找到id=" + dictMapId + "的字典");
        }
    }

    @PostMapping("/dictFieldMap/delete")
    public PlatformResponse<?> delete(HttpServletRequest request, @RequestBody MysqlDictFieldMap mysqlDictFieldMap) {
        PlatformResponse<?> response;
        try {
            mysqlDictFieldMapRepository.delete(mysqlDictFieldMap);
            response = PlatformResponse.success();
        } catch (Exception e) {
            response = PlatformResponse.failedMsg(e.getMessage());
        }
        return response;
    }

    @GetMapping("/dict/findbyfield")
    @ApiOperation(value = "根据字典filed查询")
    public PlatformResponse<Dict> findByCodeold(@ApiParam(value = "字典代码") @RequestParam(value = "dictField", required = false) String dictField,
                                                @ApiParam(value = "字典空间") @RequestParam(value = "dictSpace", required = false) String dictSpace) {
        Dict dict = dictService.findByCode(dictField, dictSpace);
        if (dict == null) {
            return PlatformResponse.failedMsg("没有查到数据");
        }
        return PlatformResponse.successData(dict);
    }

    //@PageAccessAnnotation(operMenu = "字典翻译",operType = "查询",operDesc = "字典翻译")
    @GetMapping("/dict/findbycode")
    @ApiOperation(value = "根据字典代码查询")
    public PlatformResponse<Dict> findByCode(@ApiParam(value = "字典代码id") @RequestParam(value = "dictMapId", required = false) long dictMapId) {
        Dict dict = dictService.findById(dictMapId);
        if (dict == null) {
            return PlatformResponse.failedMsg("没有查到数据");
        }
        return PlatformResponse.successData(dict);
    }

    // @PageAccessAnnotation(operMenu = "系统管理-字典管理",operType = "查询",operDesc = "字典列表")
    @GetMapping("/dict/listpage")
    @ApiOperation(value = "查询字典项分页列表")
    public PlatformResponse<Page<Dict>> listpage(
            @ApiParam(value = "表名") @RequestParam(value = "tableName", required = false) String tableName,
            @ApiParam(value = "字段名") @RequestParam(value = "fieldName", required = false) String fieldName,
            @ApiParam(value = "页码从1开始") @RequestParam(value = "pageNumber", required = false) Integer pageNumber,
            @ApiParam(value = "每页显示条数, 默认10") @RequestParam(value = "pageSize", required = false) Integer pageSize) {
        if (tableName != null && tableName.isEmpty()) {
            tableName = null;
        }
        if (fieldName != null && fieldName.isEmpty()) {
            fieldName = null;
        }
        SpecificationFactory.SpecElement codeE = new SpecificationFactory.SpecElement(SpecificationFactory.Type.EQ, "tableName", tableName);
        SpecificationFactory.SpecElement nameE = new SpecificationFactory.SpecElement(SpecificationFactory.Type.EQ, "fieldName", fieldName);
        Specification spec = SpecificationFactory.build(SpecificationFactory.OP.AND, codeE, nameE);

        if (pageNumber == null || pageNumber < 1) {
            pageNumber = 1;
        }
        if (pageSize == null || pageSize < 1) {
            pageSize = 10;
        }

        Page<Dict> page = dictService.findPage(spec, pageNumber, pageSize);
        if (!page.isEmpty()) {
            return PlatformResponse.successData(page);
        } else {
            return PlatformResponse.failedMsg("没有查询到数据");
        }
    }
}
